from playwright.sync_api import Page
from common.base_page import BasePage
from locators.agileEmergency.emergencyResourceMgr.emergencyExpertMgr.loc_expert_list import LocExpertList
from locators.agileEmergency.emergencyResourceMgr.emergencyExpertMgr.loc_expert_add import LocExpertAdd
from locators.agileEmergency.emergencyResourceMgr.emergencyExpertMgr.loc_expert_edit import LocExpertEdit
from locators.agileEmergency.emergencyResourceMgr.emergencyExpertMgr.loc_expert_detail import LocExpertDetail
from common.logger import logger

class PageExpert(BasePage):
    def __init__(self, page: Page):
        super().__init__(page)
        self.switch_menu('敏捷应急')
        self.switch_menu('应急资源管理')
        self.switch_menu('应急专家管理')

        # 初始化字段映射
        self.FIELD_MAPPING = {
            # 属性定位器映射，用于新增、编辑、查看
            'area_code': LocExpertAdd.loc_area_code,
            'name': LocExpertAdd.loc_name,
            'sex': LocExpertAdd.loc_sex,
            'id_number': LocExpertAdd.loc_id_number,
            'date_of_birth': LocExpertAdd.loc_date_of_birth,
            'age': LocExpertAdd.loc_age,
            'title': LocExpertAdd.loc_title,
            'degree': LocExpertAdd.loc_degree,
            'major': LocExpertAdd.loc_major,
            'nature': LocExpertAdd.loc_nature,
            'affiliated_unit': LocExpertAdd.loc_affiliated_unit,
            'phone': LocExpertAdd.loc_phone,
            'tel': LocExpertAdd.loc_tel,
            'email': LocExpertAdd.loc_email,
            'business_area': LocExpertAdd.loc_business_area,
            'resident_position_id': LocExpertAdd.loc_resident_position_id,
            'geom': LocExpertAdd.loc_geom,
            'resident_position_desc': LocExpertAdd.loc_resident_position_desc,
            'photo': LocExpertAdd.loc_photo,

            # 查询条件定位器映射，用于查询
            'search_name': LocExpertList.loc_search_name,
            'search_business_area': LocExpertList.loc_search_business_area,
            'search_title': LocExpertList.loc_search_title,
            'search_affiliated_unit': LocExpertList.loc_search_affiliated_unit
        }
        # 特殊字段类型
        self.SELECT_FIELDS = {'area_code', 'sex', 'title', 'degree', 'nature', 'business_area', 'resident_position_id',
                              'search_business_area', 'search_title'}
        self.DATE_FIELDS = {'date_of_birth'}
        self.FILE_FIELDS = {'photo'}

    @BasePage.register_special_field('area_code')
    def handle_area_code(self, field, value, locator, locator_class, clear_fields):
        self.select_single_tree(locator, value, level_flag=True)

    @BasePage.register_special_field('resident_position_id')
    def handle_resident_position(self, field, value, locator, locator_class, clear_fields):
        self.select(locator, value)
        self.wait_for_field_autofill(locator_class.loc_resident_position_desc)

    @BasePage.register_special_field('geom')
    def handle_geom(self, field, value, locator, locator_class, clear_fields):
        if clear_fields:
            self.clear(locator)
            self.click(locator_class.loc_geom_close)
        self.fill(locator, value)
        self.click(locator_class.loc_geom_close)

    def add_expert(self, data: dict,
                 wait_success: bool = True, screenshot: bool = False, cancel: bool = False):
        """
        新增
        
        参数说明:
        - data: 包含数据的字典，键为字段名，值为字段值
        - wait_success: 是否等待保存成功提示，默认为True
        - screenshot: 是否在操作前截图，默认为False
        - cancel: 是否点击取消，默认为False
        - colse: 是否点击关闭弹窗，默认为False
        """
        # 点击新增按钮
        logger.info('点击新增按钮')
        self.click(LocExpertList.loc_add)

        logger.info('填写表单')
        self.fill_form(LocExpertAdd, data)

        if cancel:
            # 取消操作
            logger.info('点击取消自动关闭弹窗，不新增数据')
            self.click(LocExpertAdd.loc_cancel)
        else:
            # 提交表单
            logger.info('点击确定按钮保存数据')
            self.click(LocExpertAdd.loc_sure)

            # 等待操作完成
            if wait_success:
                self.wait_for_message("操作成功")

        if screenshot:
            self.take_screenshot("新增提交后")

        return self

    def search_expert(self, data: dict, screenshot: bool = False):
        """
        查询

        参数说明:
        - data: 包含数据的查询条件字典，键为字段名，值为字段值
        - screenshot: 是否操作截图，默认为False
        """

        logger.info('查询列表')

        logger.info('输入查询条件')
        self.fill_form(LocExpertList, data)

        logger.info('点击查询')
        self.click(LocExpertList.loc_search)

        if screenshot:
            self.take_screenshot("查询结果")

        return self

    def edit_expert(self, search_name: str, data: dict,
                  wait_success: bool = True, screenshot: bool = False, cancel: bool = False):
        """
        编辑

        参数说明:
        - search_name: 查询字段，搜索编辑目标数据。尽量是精准查询出唯一值。
        - data: 包含数据的字典，键为字段名，值为字段值
        - wait_success: 是否等待保存成功提示，默认为True
        - screenshot: 是否在操作前截图，默认为False
        - cancel: 是否点击取消，默认为False
        """

        logger.info('找到要编辑的数据')
        self.fill(LocExpertList.loc_search_name, search_name)
        self.click(LocExpertList.loc_search)
        self.page.get_by_text("共 1 条").wait_for(state="visible", timeout=15000)

        logger.info('点击编辑按钮')
        self.click(LocExpertList.loc_edit)

        # 编辑字段
        logger.info('编辑表单')
        self.fill_form(LocExpertEdit, data, clear_fields=True)

        if cancel:
            # 取消操作
            logger.info('点击取消，不保存编辑的数据')
            self.click(LocExpertEdit.loc_cancel)
        else:
            # 提交表单
            logger.info('点击确定保存编辑的信息')
            self.click(LocExpertEdit.loc_sure)

            # 等待操作完成
            if wait_success:
                self.wait_for_message("操作成功")

        if screenshot:
            self.take_screenshot("编辑提交后")

        return self

    def detail_expert(self, search_name: str, data: dict,
                    screenshot: bool = False):
        """
        查看

        参数说明:
        - search_name: 查询字段，搜索查看目标数据。尽量是精准查询出唯一值。
        - data: 包含数据的字典，键为字段名，值为字段值
        - screenshot: 是否在操作前截图，默认为False
        """

        # 点击查看按钮
        logger.info('找到要查看的数据')
        self.fill(LocExpertList.loc_search_name, search_name)
        self.click(LocExpertList.loc_search)
        self.page.get_by_text("共 1 条").wait_for(state="visible", timeout=15000)

        logger.info('点击查看按钮')
        self.click(LocExpertList.loc_detail)

        logger.info('查看并验证数据')

        # 验证每个字段
        for field, expected_value in data.items():
            if expected_value is None or expected_value == "":
                continue

            locator = getattr(LocExpertDetail, f"loc_{field}", None)
            if not locator:
                logger.warning(f"未找到字段 '{field}' 的定位器，跳过验证")
                continue

            actual_value = self.get_loc_value(locator)
            assert actual_value == expected_value, (
                f"字段 [{field}] 验证失败: 期望值 '{expected_value}', 实际值 '{actual_value}'"
            )
            logger.info(f"字段 [{field}] 验证通过: {expected_value}")

        if screenshot:
            self.take_screenshot("查看截图")

        # 关闭详情页
        self.click(LocExpertDetail.loc_close)

        return self

    def delete_expert(self, search_name: str,
                    wait_success: bool = True, screenshot: bool = False, cancel: bool = False):
        """
        删除

        参数说明:
        - search_name: 查询字段，搜索要删除的目标数据。尽量是精准查询出唯一值。
        - wait_success: 是否等待保存成功提示，默认为True
        - screenshot: 是否在操作前截图，默认为False
        - cancel: 是否点击取消，默认为False
        """

        # 勾选要删除的数据，点击删除按钮
        self.fill(LocExpertList.loc_search_name, search_name)
        self.click(LocExpertList.loc_search)
        self.page.get_by_text("共 1 条").wait_for(state="visible", timeout=15000)

        logger.info('通过关键字找到数据行，并勾选对应行')
        self.select_row_checkbox(target_value=search_name)
        logger.info('点击删除按钮')
        self.click(LocExpertList.loc_delete)

        if cancel:
            # 取消操作
            logger.info('点击取消，不删除勾选的数据')
            self.click(LocExpertList.loc_cancel)
        else:
            # 确定删除
            logger.info('点击确定删除勾选的数据')
            self.click(LocExpertList.loc_sure)

            # 等待操作完成
            if wait_success:
                self.wait_for_message("操作成功")

        if screenshot:
            self.take_screenshot("删除后截图")